package com.duojuhe.coremodule.system.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.cache.SystemParameterCache;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.common.utils.thread.ThreadUtils;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.system.entity.SystemDict;
import com.duojuhe.coremodule.system.entity.SystemParameter;
import com.duojuhe.coremodule.system.mapper.SystemParameterMapper;
import com.duojuhe.coremodule.system.pojo.dto.parameter.*;
import com.duojuhe.coremodule.system.service.SystemParameterService;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class SystemParameterServiceImpl  extends BaseService implements SystemParameterService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private SystemParameterCache systemParameterCache;
    @Resource
    private SystemParameterMapper systemParameterMapper;

    /**
     * 项目启动时，初始系统参数
     */
    @PostConstruct
    public void initSystemDictToCache() {
        log.info("=====初始系统参数到缓存中开始=====");
        loadingSystemParameterCache();
        log.info("=====初始系统参数到缓存中结束=====");
    }


    /**
     * 【根据code集合获取系统参数】根据code集合获取系统参数
     * @param req
     * @return
     */
    @Override
    public ServiceResult<Map<String, SystemParameter>> querySystemParameterListByParameterCodeList(SystemParameterCodeListReq req) {
        Map<String,SystemParameter> stringSystemParameterMap = new HashMap<>();
        for (String parameterCode:req.getParameterCodeList()){
            stringSystemParameterMap.put(parameterCode,systemParameterCache.getSystemParameterByParameterCode(parameterCode));
        }
        return ServiceResult.ok(stringSystemParameterMap);
    }

    /**
     * 【分页查询】分页查询系统参数list
     * @param req
     * @return
     */
    @Override
    public ServiceResult<PageResult<List<QuerySystemParameterPageRes>>> querySystemParameterPageResList(QuerySystemParameterPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "createTime desc,parameterCode desc, parameterId desc");
        List<QuerySystemParameterPageRes> list = systemParameterMapper.querySystemParameterPageResList(req);
        for (QuerySystemParameterPageRes res:list){
            SystemDict dictBuiltIn = systemDictCache.getSystemDictByDictCode(res.getBuiltIn());
            res.setBuiltInName(dictBuiltIn.getDictName());
            res.setBuiltInColor(dictBuiltIn.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req,list);
    }

    /**
     * 【新增】新增系统参数
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult saveSystemParameter(SaveSystemParameterReq req) {
        //检查系统参数编码是否存在
        checkSystemParameterCodeExist(req.getParameterCode());
        //当前时间
        Date date = new Date();
        //参数ID
        String parameterId = UUIDUtils.getUUID32();
        //构建参数对象
        SystemParameter systemParameter = new SystemParameter();
        systemParameter.setParameterId(parameterId);
        systemParameter.setParameterCode(req.getParameterCode());
        systemParameter.setDescription(req.getDescription());
        systemParameter.setParameterName(req.getParameterName());
        systemParameter.setParameterValue(req.getParameterValue());
        systemParameter.setCreateTime(date);
        systemParameter.setUpdateTime(date);
        systemParameter.setBuiltIn(SystemEnum.YES_NO.NO.getKey());
        int row = systemParameterMapper.insertSelective(systemParameter);
        if (row>0){
            systemParameterCache.putSystemParameterCache(systemParameter);
        }
        return ServiceResult.ok(parameterId);
    }

    /**
     * 【修改】修改系统参数
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult updateSystemParameter(UpdateSystemParameterReq req) {
        SystemParameter systemParameter = systemParameterMapper.selectByPrimaryKey(req.getParameterId());
        if (systemParameter == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //系统参数编码
        String parameterCode = req.getParameterCode();
        //如果不是和当前编码一致则判断是否存在
        if (!systemParameter.getParameterCode().equals(parameterCode)){
            //检查系统参数编码是否存在
            checkSystemParameterCodeExist(parameterCode);
        }
        systemParameter.setParameterName(req.getParameterName());
        systemParameter.setParameterCode(req.getParameterCode());
        systemParameter.setParameterValue(req.getParameterValue());
        systemParameter.setUpdateTime(new Date());
        systemParameter.setDescription(req.getDescription());
        int row = systemParameterMapper.updateByPrimaryKeySelective(systemParameter);
        if (row>0){
            systemParameterCache.putSystemParameterCache(systemParameter);
        }
        return ServiceResult.ok(req.getParameterId());
    }

    /**
     * 删除系统参数
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult deleteSystemParameterByParameterId(SystemParameterIdReq req) {
        //系统参数id
        String parameterId = req.getParameterId();
        SystemParameter systemParameter = systemParameterMapper.selectByPrimaryKey(parameterId);
        if (systemParameter == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        if (SystemEnum.YES_NO.YES.getKey().equals(systemParameter.getBuiltIn())) {
            return ServiceResult.fail(ErrorCodes.SYSTEM_PARAMETER_BUILT_IN_NOT_DELETE);
        }
        //删除数据库
        int row = systemParameterMapper.deleteByPrimaryKey(parameterId);
        if (row>0){
            //删除缓存
            systemParameterCache.deleteSystemParameterByParameterCode(systemParameter.getParameterCode());
        }
        return ServiceResult.ok(parameterId);
    }


    /**
     * 加载系统参数缓存数据
     */
    @Override
    public void loadingSystemParameterCache() {
        //先清除
        systemParameterCache.clearSystemParameterCache();
        //在插入
        systemParameterCache.putSystemParameterCache(systemParameterMapper.selectAll());
    }


    /**
     * 清空系统参数缓存数据
     */
    @Override
    public void clearSystemParameterCache() {
        systemParameterCache.clearSystemParameterCache();
    }

    /**
     * 重置系统参数缓存数据
     */
    @Override
    public ServiceResult resetSystemParameterCache() {
      ThreadUtils.execute(() -> {
          try {
            //先清空之前的
            clearSystemParameterCache();
            //加载新的
            loadingSystemParameterCache();
            }catch (Exception e){
                log.error("重置系统参数缓存出现异常",e);
            }
        });
        return ServiceResult.ok(ErrorCodes.SUCCESS);
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 查询参数code编码是否已经存在
     */
    private void checkSystemParameterCodeExist(String parameterCode) {
        if (StringUtils.isBlank(parameterCode)){
            throw new DuoJuHeException(ErrorCodes.SYSTEM_PARAMETER_CODE_EXIST);
        }
        Example example = new Example(SystemParameter.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parameterCode", parameterCode);
        if(systemParameterMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.SYSTEM_PARAMETER_CODE_EXIST);
        }
    }
}
